#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>

typedef struct {
	float x, y;
}Punto;

Punto vertices[2];
int numPuntos;
int screen[640][480];

void inicializar (void);
void redimensiona (int alto, int ancho);
void dibuja (void);
void teclado (unsigned char key, int cx, int cy);
void raton (int boton, int estado, int cx, int cy);
void ddaAlgorithm(int, int, int, int);
void limpiaScreen();
int my_round(float);

int main(int argc, char* argv[]) {

   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   glutInitWindowSize (640, 480);
   glutInitWindowPosition (100, 105);
   glutCreateWindow ("Algoitmo DDA");
   inicializar();

   glutDisplayFunc(dibuja);
   glutReshapeFunc(redimensiona);
   glutKeyboardFunc(teclado);
   glutMouseFunc(raton);
   glutMainLoop();

   return 0;
}

void inicializar () {
   glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
   numPuntos = 0;

}

void redimensiona (int ancho, int alto) {

   glViewport(0, 0, ancho, alto);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();

   gluOrtho2D(0.0, (double)ancho, 0.0, (double)alto);
}

void teclado (unsigned char key, int cx, int cy) {

	switch (key) {
		case 27:
		   exit(0);
		break;

		default: break;
	}

	glutPostRedisplay();
}

void raton (int boton, int estado, int cx, int cy) {


	if (boton == GLUT_LEFT_BUTTON && estado == GLUT_DOWN) {

		if (numPuntos == 2) {
			numPuntos = 0;
		}

		vertices[numPuntos].x = cx;
		vertices[numPuntos].y = 480 - cy;

		numPuntos++;

	}

	glutPostRedisplay();
}


void dibuja (void) {
	int i, j;

	glClear(GL_COLOR_BUFFER_BIT);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	limpiaScreen();
	if (numPuntos == 2) {
		ddaAlgorithm((int)vertices[0].x, (int)vertices[0].y, (int)vertices[1].x, (int)vertices[1].y);
	}

	glPointSize(1.0);
	glColor3f(1.0, 0.0, 0.0);
	glBegin(GL_POINTS);
		for(i = 0; i < 640; i++) {
			for(j = 0; j < 480; j++) {
				if (screen[i][j]) {
					glVertex2i(i, j);
				}
			}
		}
	glEnd();

	glPointSize(4.0);
	glColor3f(1.0, 1.0, 0.0);
	glBegin(GL_POINTS);
		for (i = 0; i < numPuntos; i++) {
			glVertex2f(vertices[i].x, vertices[i].y);
		}
	glEnd();

	glFlush();
}


void ddaAlgorithm(int x0, int y0, int x1, int y1) {
	int longitudX, longitudY, longitud, i;
	float Dx, Dy, x, y;

	longitudX = x1 - x0;
	longitudY = y1 - y0;

	longitud = (abs(longitudX) > abs(longitudY)) ? abs(longitudX) : abs(longitudY);

	Dx = (float) longitudX / (float) longitud;
	Dy = (float) longitudY / (float) longitud;

	x = x0;
	y = y0;

	for(i = 0; i <= longitud; i++) {
		screen[my_round(x)][my_round(y)] = 1;
		x += Dx;
		y += Dy;
	}

}

void limpiaScreen() {
	int i, j;

	for (i = 0; i < 640; i++) {
		for (j = 0; j < 480; j++) {
			screen[i][j] = 0;
		}
	}
}

int my_round (float n) {
	return floor(n + 0.5);
}
